<?php

namespace App\Services\Base;
use App\Exceptions\BusinessException;
use App\Common\ResponseCode;
use App\Models\Base\Menu;
use App\Params\Backend\MenuListParams;
use App\Params\Backend\MenuUpdateParam;
use App\Repository\MenuRepository;
use App\Repository\ResourceRepository;
use App\Repository\RoleRepository;
use App\Services\BaseService;

/**
 * 系统菜单业务类
 *
 * @author WangBin
 * @date 2021-09-24
 * @package App\Http\Services
 */
class MenuService extends BaseService
{
    /**
     * 获取菜单（树形结构）
     *
     * @param
     * @return \Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection
     */
    public function getList(MenuListParams $filter)
    {
        // 获取用户可用的菜单（二级菜单）
        $menuIds = MenuRepository::getInstance()->getUserMenu($filter->getUserId())->pluck('menu_id')->toArray();
        if($filter->getWithTree()) {
            // 根据一级菜单获取取子菜单
            $menu = MenuRepository::getInstance()->getByLevel(1);
            $menu->each(function ($item) use ($menuIds){
                $children = MenuRepository::getInstance()->getByParentId($item->menu_id);
                $children = $children->filter(function ($item) use ($menuIds){
                    return in_array($item->menu_id, $menuIds);
                });
                $children->each(function ($child){
                    $child->id = $child->menu_id;
                    $child->name = $child->menu_name;
                    $child->is_show = true;
                    // 获取二级菜单的可用资源
                    $child->resources = ResourceRepository::getInstance()->getByMenuId($child->menu_id)->pluck('resource_code');
                });
                $item->childList = $children;
                $item->id = $item->menu_id;
                $item->name = $item->menu_name;
                $item->is_show = true;
            });
            return $menu;
        }

        $level = $filter->getLevel() ?? 0;
        if($level) {
            $menu = Menu::getByLevel($level);
        } else {
            return $this->toList(Menu::getByFilter($filter), $filter->getPage(), $filter->getPageSize());
        }
        return $menu;
    }

    /**
     * 获取菜单（中台初始化）
     *
     * @param $roleId = 0
     * @return
     */
    public function getTree(int $roleId = 0)
    {
        // 获取全部可用菜单
        $menus = MenuRepository::getInstance()->getList(['is_active' => 1])->get();
        // 根据菜单级数分组并排序
        $menusGrouped = $menus->groupBy('level')->toArray();
        // 取出一级菜单并排序
        $menu1 = collect($menusGrouped[1])->sortBy('sort_num')->toArray();
        // 获取二级菜单
        $menu2 = collect($menusGrouped[2]);
        // 根据角色过滤二级菜单
        if($roleId) {
            $roleMenu = RoleRepository::getInstance()->getRoleMenu($roleId)->pluck('menu_id')->toArray();
            $menu2 = $menu2->filter(function ($item) use ($roleMenu) {
                return in_array($item['menu_id'], $roleMenu);
            });
        }
        // 处理一级菜单数据
        foreach ($menu1 as &$item) {
            $item['id'] = $item['menu_id'];
            $item['title'] = $item['menu_name'];
            $item['icon'] = "layui-icon " . $item['icon'];
            $item['href'] = $item['url'];
            $item['type'] = 0;
            $children = $menu2->where('parent_id', $item['menu_id'])->toArray();
            foreach ($children as &$child) {
                $child['type'] = 1;
                $child['openType'] = '_iframe';
                $child['id'] = $child['menu_id'];
                $child['title'] = $child['menu_name'];
                $child['icon'] = "layui-icon " . $child['icon'];
                $child['href'] = $child['url'];
            }
            $item['children'] = collect($children)->sortBy('sort_num')->values();
        }
        return $menu1;
    }

    /**
     * 保存菜单
     *
     * @param array $data
     * @return bool
     * @throws BusinessException
     */
    public function update(MenuUpdateParam $data)
    {
        $data = $data->toArray();
        return MenuRepository::getInstance()->save($data, $data['menu_id']);
    }

    /**
     * 菜单详情
     *
     * @param int $menuId
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     * @throws BusinessException
     */
    public function get(int $menuId)
    {
        $menu = Menu::getById($menuId);
        if(is_null($menu)) {
            throw new BusinessException(ResponseCode::MENU_NOT_FOUND);
        }
        return $menu;
    }

    /**
     * 停用/启用菜单
     *
     * @param int $menuId
     * @return int
     * @throws BusinessException
     */
    public function enable(int $menuId)
    {
        $menu = Menu::getById($menuId);
        if(is_null($menu)) {
            throw new BusinessException(ResponseCode::MENU_NOT_FOUND);
        }
        $isActive = 1;
        if($menu->is_active == 1) {
            $isActive = 0;
        }
        return Menu::enable($menuId, $isActive);
    }

    /**
     * 删除菜单
     *
     * @param int $menuId
     * @return bool|mixed|null
     * @throws BusinessException
     */
    public function delete(int $menuId)
    {
        $menu = Menu::getById($menuId);
        if(is_null($menu)) {
            throw new BusinessException(ResponseCode::MENU_NOT_FOUND);
        }
        // 如果存在子菜单，则需先删除子菜单
        if($menu->level == 1) {
            throw new BusinessException(ResponseCode::MENU_DELETE_PARENT_FAIL);
        }
        // 删除菜单
        return Menu::remove($menuId);
    }
}
